import React, { useEffect, useMemo, useState } from 'react';
import { Button, Card, message, Table, Pagination, Modal, Form, Input, Switch, Spin, Tree, TreeProps } from 'antd';
import { useDispatch, useSelector } from 'react-redux';
import { Page, Role as RoleType } from '@/type/RoleType';
import { fetchRoleList, deleteRole, addRole, findRole, updateRole } from '@/store/modules/roleStore';
import { ExclamationCircleFilled } from '@ant-design/icons';
import { assignRole, fetchPermissionList } from '@/store/modules/permissionStore';
import './Role.scss';


const Role: React.FunctionComponent = () => {
  const dispatch = useDispatch();
  const roleList = useSelector((state: any) => state.roleStore.roleList);
  const total = useSelector((state: any) => state.roleStore.total);
  const permissionTree = useSelector((state: any) => state.permissionStore.permissionTree);
  const [form] = Form.useForm();
  const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
  const [page, setPage] = useState<Page>({ page: 1, pagesize: 10 });
  const columns = [
    { title: 'ID', dataIndex: 'id', key: 'id' },
    { title: '角色', dataIndex: 'name', key: 'name' },
    { title: '启用', key: 'state', render: (_: RoleType, record: RoleType) => <span>{record.state === 0 ? '未启用' : '已启用'}</span> },
    { title: '描述', dataIndex: 'description', key: 'description' },
    {
      title: '操作',
      render: (_: RoleType, record: RoleType) => (
        <>
          <Button type="primary" onClick={() => handleAssignAuth(record)}>分配权限</Button> <Button type="primary" onClick={() => handleEdit(record)}>编辑角色</Button> <Button type="primary" danger onClick={() => handleDelete(record)}>删除角色</Button>
        </>
      ),
    },
  ];
  const [formData, setFormData] = useState<RoleType>({ description: '', name: '', state: 0 });
  const [edit, setEdit] = useState<boolean>(false);
  const roleTitle = useMemo(() => edit ? '编辑角色' : '添加角色', [edit]);
  const [loading, setLoading] = useState<boolean>(false);
  const [isAssignAuth, setIsAssignAuth] = useState<boolean>(false);


  const [defaultCheckedKeys, setDefaultCheckedKeys] = useState<number[]>([]);
  /**
   * @description 获取分页查询角色列表的回调函数
   * */
  const fetchRoles = async (page: Page) => {
    try {
      setLoading(true);
      await dispatch(fetchRoleList(page)).unwrap();
    } catch (rejectedValueOrSerializedError: any) {
      message.error(rejectedValueOrSerializedError);
    } finally {
      setLoading(false);
    }
  };

  /**
   * @description 获取所有权限点的回调函数
   * */
  const fetchPermission = async () => {
    try {
      await dispatch(fetchPermissionList()).unwrap();
    } catch (rejectedValueOrSerializedError: any) {
      message.error(rejectedValueOrSerializedError);
    }
  };
  /**
   * @description 分页器变化的回调函数
   * */
  const changePagination = (page: number, pagesize: number) => {
    const newPage: Page = { page, pagesize };
    setPage(newPage);
    fetchRoles(newPage);
  };

  /**
   * @description 点击删除按钮的回调函数
   * */
  const handleDelete = async (record: RoleType) => {
    Modal.confirm({
      title: '温馨提示',
      icon: <ExclamationCircleFilled />,
      content: `确认删除${record.name}吗?`,
      okText: '确定',
      cancelText: '取消',
      onOk: async (): Promise<void> => {
        try {
          const deleteMessage = await dispatch(deleteRole(record.id)).unwrap();
          await fetchRoles(page);
          message.success(deleteMessage);
        } catch (rejectedValueOrSerializedError: any) {
          message.error(rejectedValueOrSerializedError);
        }
      },
    });
  };

  /**
   * @description 点击确定按钮的回调函数
   * */
  const handleOk = async () => {
    if (edit) {
      try {
        const newFormData = { ...formData, ...form.getFieldsValue(), state: formData.state ? 0 : 1 };
        setFormData(newFormData);
        const updateMessage = await dispatch(updateRole(newFormData)).unwrap();
        await fetchRoles(page);
        setIsModalOpen(false);
        message.success(updateMessage);
      } catch (rejectedValueOrSerializedError: any) {
        message.error(rejectedValueOrSerializedError);
      }
    } else {
      try {
        const newFormData = form.getFieldsValue();
        setFormData(newFormData);
        const addMessage = await dispatch(addRole(newFormData)).unwrap();
        await fetchRoles(page);
        setIsModalOpen(false);
        message.success(addMessage);
      } catch (rejectedValueOrSerializedError: any) {
        message.error(rejectedValueOrSerializedError);
      }
    }
  };

  const handleCancel = () => {
    setIsModalOpen(false);
  };

  /**
   * @description 点击添加角色按钮的回调函数
   * */
  const handleAdd = () => {
    setIsModalOpen(true);
    setEdit(false);
  };

  /**
   * @description 点击编辑角色按钮的回调函数
   * */
  const handleEdit = async (record: RoleType) => {
    try {
      const roleDetail = await dispatch(findRole(record.id)).unwrap();
      setFormData(roleDetail);
      form.setFieldsValue(roleDetail);
      setEdit(true);
      setIsModalOpen(true);
    } catch (rejectedValueOrSerializedError: any) {
      message.error(rejectedValueOrSerializedError);
    }
  };

  /**
   * modal组件打卡或者关闭的回调函数
   * */
  const afterOpenChange = (open: boolean) => {
    if (!open) form.resetFields();
  };


  const handleAssignAuth = async (record: RoleType) => {
    await fetchPermission();
    const roleDetail = await dispatch(findRole(record.id)).unwrap();
    setFormData(roleDetail);
    setDefaultCheckedKeys(roleDetail.permIds);
    setIsAssignAuth(true);
  };


  const assignAuthCancel = () => {
    setIsAssignAuth(false);
  };


  const assignAuthOpenChange = (open: boolean) => {
    if (!open) {
      setDefaultCheckedKeys([]);
    }
  };

  const onCheck: TreeProps['onCheck'] = (checkedKeysValue) => {
    setDefaultCheckedKeys(checkedKeysValue as number[]);
  };

  /**
   * @description 确定分配权限的回调阿含
   * */
  const handleSubmitAuth = async () => {
    try {
      const data = { id: formData.id, permIds: defaultCheckedKeys };
      const assignMessage = await dispatch(assignRole(data)).unwrap();
      setIsAssignAuth(false);
      message.success(assignMessage);
    } catch (rejectedValueOrSerializedError: any) {
      message.error(rejectedValueOrSerializedError);
    }
  };

  const renderTable = () => {
    if (loading) {
      return (
        <div className="loading">
          <Spin spinning={loading} size="large">加载中</Spin>
        </div>
      );
    } else {
      return (
        <Table rowKey={'id'} dataSource={roleList} columns={columns} bordered pagination={false}></Table>
      );
    }
  };


  useEffect(() => {
    fetchRoles(page);
  }, []);

  return (
    <div className="role layui-anim layui-anim-scale">
      <Card>
        <Button type="primary" onClick={handleAdd}>添加角色</Button>
        {
          renderTable()
        }
        <Pagination showSizeChanger defaultCurrent={page.page} total={total} onChange={changePagination} />
      </Card>
      <Modal width={700} title={roleTitle} open={isModalOpen} onOk={handleOk} onCancel={handleCancel} afterOpenChange={afterOpenChange}>
        <Form form={form}>
          <Form.Item label="角色名称" name="name">
            <Input placeholder="请输入角色名称"></Input>
          </Form.Item>
          <Form.Item label="是否启用" name="state">
            <Switch />
          </Form.Item>
          <Form.Item label="角色描述" name="description">
            <Input.TextArea placeholder="请输入角色描述" rows={4} maxLength={6}></Input.TextArea>
          </Form.Item>
        </Form>
      </Modal>
      <Modal width={700} title="角色分配权限" open={isAssignAuth} onOk={handleSubmitAuth} onCancel={assignAuthCancel} afterOpenChange={assignAuthOpenChange}>
        {
          permissionTree && <Tree defaultExpandAll showLine checkable checkedKeys={defaultCheckedKeys} onCheck={onCheck} fieldNames={{ title: 'name', key: 'id', children: 'children' }} treeData={permissionTree} />
        }
      </Modal>
    </div>
  );
};

export default Role;
